﻿using System;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace GTAFingerprinterCore.Keyboards
{
    public class Keyboarder
    {
        private const uint MAPVK_VK_TO_VSC = 0;

        [DllImport("user32.dll", EntryPoint = "MapVirtualKey")]
        private static extern uint MapVirtualKey(
            Keys uCode,
            uint uMapType);

        [DllImport("user32.dll", EntryPoint = "keybd_event", SetLastError = true)]
        public static extern void keybd_event(Keys bVk, byte bScan, uint dwFlags, uint dwExtraInfo);

        public static async Task SendKey(Keys key, int count = 1, int delay = 20)
        {
            if (count == 0) return;
            uint extended = 0;
            if (key == Keys.Up || key == Keys.Down || key == Keys.Left || key == Keys.Right)
                extended = 1;
            var scan = (byte)MapVirtualKey(key, 0);
            for (int i = 0; i < count; i++)
            {
                keybd_event(key, scan, extended, 0);
                await Task.Delay(delay);
                keybd_event(key, scan, extended | 2, 0);
                await Task.Delay(delay);
            }
        }


        [Flags]
        public enum MouseEventFlags
        {
            LeftDown = 0x00000002,
            LeftUp = 0x00000004,
            MiddleDown = 0x00000020,
            MiddleUp = 0x00000040,
            Move = 0x00000001,
            Absolute = 0x00008000,
            RightDown = 0x00000008,
            RightUp = 0x00000010
        }
        [DllImport("user32.dll")]
        private static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool GetCursorPos(out MousePoint lpMousePoint);
        public static MousePoint GetCursorPosition()
        {
            MousePoint currentMousePoint;
            var gotPoint = GetCursorPos(out currentMousePoint);
            if (!gotPoint) { currentMousePoint = new MousePoint(0, 0); }
            return currentMousePoint;
        }

        public static void MouseEvent(MouseEventFlags value)
        {
            MousePoint position = GetCursorPosition();

            mouse_event
                ((int)value,
                 position.X,
                 position.Y,
                 0,
                 0)
                ;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct MousePoint
        {
            public int X;
            public int Y;

            public MousePoint(int x, int y)
            {
                X = x;
                Y = y;
            }
        }
    }
}